<?php
class App_Page_Model_Page extends Main_Db_Table_Abstract
{
	/**
	 * @var string
	 */
	protected $_name = 'page';
	
	/**
	 * @var string
	 */
	protected $_primary = 'id';
	
	/**
	 * @var bool
	 */
	protected $_isTree = true;
	
	/**
	 * @var array
	 */
	protected $_fields = array(
		'id',
	    'lft',
	  	'rgt',
	  	'parent_id',
		'level'
	);
	
	/**
	 * @var App_Page_Model_PageI18n
	 */
	protected $_modelPageI18n;

	/**
	 * 
	 * @var App_Page_Model_PageObject
	 */
	protected $_modelPageObject;
	
	/**
	 * @return void
	 */
	public function init() 
	{
		$this->_modelPageI18n = Main_Model::factory('Page_Model_PageI18n');
		$this->_modelPageObject = Main_Model::factory('Page_Model_PageObject');
	}

	/**
	 * @return array
	 */
	public function getAll() 
	{
		$sql = "
			SELECT
				p.id
				, p.parent_id
				, p.level
				, p_o.name
			FROM 
				page p
			INNER JOIN
				page_object p_o
				ON
					(p.id = p_o.page_id)
			ORDER BY p.lft						
		";
		
		$list = $this->getAdapter()->fetchAll($sql);
		return $list;
	}
	
	
	/**
	 * @return array
	 */
/*	public function getAllIdAndUrl()
	{
		$sql = "
			SELECT
				p.id
				, p_o.agg_url
				, p.level
			FROM 
				page p
			INNER JOIN
				page_object p_o
				ON
					(p.id = p_o.page_id)
			ORDER BY p.lft						
		";
		
		$list = $this->getAdapter()->fetchAll($sql);
		
		return $list;
	}*/
	
	/**
	 * @param array $data
	 * @return bool
	 */
	public function insertItem($data) 
	{
		$dataOk = $this->beforeSave($data, array(
			'parent_id' 
		));
		
		$result = $this->insert($dataOk);
				
		$data['page_id'] = $this->lastInsertId();
		$res1 = $this->_modelPageI18n->insertItem($data);
		$res2 = $this->_modelPageObject->insertItem($data); 
		
		return $result && $res1 && $res2;
	}
	
	/**
	 * @param array $data
	 * @param int $id
	 * @return bool
	 */
	public function updateItem($data, $id)
	{
		$node = $this->getNodeById($id);
		if ($node['level'] > 1) {
			$data['parent_id'] = ($data['parent_id'] == 0) ? null : $data['parent_id'];
			$oldParentId = $node['parent_id']; 
			$wasParentChanged = $oldParentId != $data['parent_id'];
			if ($wasParentChanged) {
				$this->moveNode($id, $data['parent_id']);		
			}
		} else {
			$wasParentChanged = false;
		}
		
		$res1 = $this->_modelPageObject->updateItem($data, $id, $wasParentChanged);
		$res2 = $this->_modelPageI18n->updateItem($data, $id);  	
		return $res1 && $res2; 
	}
	
	/**
	 * @param int $id
	 * @return array
	 */
	public function getNodeById($id) 
	{
		$id = $this->escape($id);
		
		$sql = "
			SELECT 
				id
				, lft
				, rgt
				, level
				, parent_id
			FROM
				page
			WHERE
				id=$id			
		";

		$list = $this->getAdapter()->fetchRow($sql);
		return $list;
	}
	
	/**
	 * @param string $name
	 * @param int $parentId
	 * @param int $langId 
	 * @return array
	 */
	public function getItemByNameAndParentId($name, $parentId, $langId)
	{
		$name = $this->escape($name);
		$parentId = ($parentId != null) ? $this->escape($parentId) : 'null';
		
		$sql = "
			SELECT 
				p.id
				, p.lft
				, p.rgt
				, p.parent_id
				, p.level
				, p_o.name
				, l.name as layout_name
				, p_o.f_map
				, p_o.f_active
				, p_i18n.meta_title
				, p_i18n.meta_description
				, p_i18n.meta_keywords
			FROM
				page p
			INNER JOIN
				page_object p_o
				ON
					(p.id=p_o.page_id)
			INNER JOIN
				layout l
				ON		
					(p_o.layout_id=l.id)			
			INNER JOIN
				page_i18n p_i18n
				ON
					(p.id=p_i18n.page_id AND p_i18n.lang_id={$langId})
			WHERE
				p_o.name='{$name}' AND p.parent_id={$parentId} 			
		";

		$list = $this->getAdapter()->fetchRow($sql);
		return $list;
	}
	
	/**
	 * @param int $id
	 * @param int $langId
	 * @return array
	 */
	public function getItemById($id, $langId) 
	{
		$id = $this->escape($id);
		
		$sql = "
			SELECT 
				p.id
				, p.lft
				, p.rgt
				, p.parent_id
				, p.level
				, p_o.name
				, l.name as layout_name
				, p_o.f_map
				, p_o.f_active
				, p_i18n.meta_title
				, p_i18n.meta_description
				, p_i18n.meta_keywords
			FROM
				page p
			INNER JOIN
				page_object p_o
				ON
					(p.id=p_o.page_id)
			INNER JOIN
				layout l
				ON		
					(p_o.layout_id=l.id)			
			INNER JOIN
				page_i18n p_i18n
				ON
					(p.id=p_i18n.page_id AND p_i18n.lang_id={$langId})
			WHERE
				p.id={$id}		
		";
		
		$list = $this->getAdapter()->fetchRow($sql);
		return $list;
	}
	
	/**
	 * @param int $id
	 * @return array
	 */
	public function getAscendantBranchIdAndName($id) 
	{
		$id = $this->escape($id);
		
		$sql = "
			SELECT 
				p.id, p_o.name
			FROM
				page p
			LEFT JOIN
				page p2	
				ON 
					(p2.id=$id)
			INNER JOIN
				page_object p_o
				ON
					(p.id = p_o.page_id)		
			WHERE
				p.lft < p2.lft AND p.rgt > p2.rgt   
		";
		$list = $this->getAdapter()->fetchAll($sql);
		$list = Main_Function::expandList($list, 'id', 'name');
		
		return $list;
	}
	
	/**
	 * @param int $id
	 * @return bool
	 */
	public function deleteItem($id) 
	{
		$id = $this->escape($id);
		$res1 = $this->_modelPageI18n->deleteItemByPageId($id);
		$res2 = $this->_modelPageObject->deleteItemByPageId($id); 
		
		$res3 = $this->_deleteBlocksByBranchNode($id);
		
		if ($res1 && $res2 && $res3) {
			return $this->deleteBranch($id);
		} else {
			return false;
		}	
	}

	/**
	 * @param int $id
	 * @return bool
	 */
	private function _deleteBlocksByBranchNode($id) 
	{
		$pageIds = array(0 => $id) + $this->getNodeDescendantIds($id);
		
		$pageIdsStr = implode(',', $pageIds);  	
		return $this->getAdapter()->delete('page_block', "id IN ($pageIdsStr)");
	} 
	
	
	/**
	 * @param int $id
	 * @return array
	 */
	public function getNodeDescendantIds($id) 
	{
		$id = $this->escape($id);
		
		$sql = "
			SELECT 
				p1.id
			FROM
				page p1
			LEFT JOIN
				page p2
				ON
					(p2.id=$id) 
			WHERE
				p1.lft > p2.lft AND p1.lft < p2.rgt 
		";
		
		$list = $this->getAdapter()->fetchAll($sql);
		$list = Main_Function::expandList($list, 'id', 'id');
		
		return $list;
	}
	
	/**
	 * @param int $pageId
	 * @return array
	 */    
    public function getBlockStatisticsInPage($pageId)
    {
    	$pageId = $this->escape($pageId);
    	
		$sql = "
			SELECT
				lang_id, COUNT(*) count
			FROM
				page_block
			WHERE
				page_id={$pageId}
			GROUP BY
				lang_id	
		";
		$list = $this->getAdapter()->fetchAll($sql);

		if (empty($list)) { 
			return $list;
		}	
		
		foreach ($list as $key => $val) {
			if (empty($val['lang_id'])) {
				$list[$key]['lang_id'] = 0; 
			}
		}
		
		$res = Main_Function::expandList($list, 'lang_id', 'count');
		
		return $res;
    }
} 
